home *** CD-ROM | disk | FTP | other *** search
/ PC Graphics Unleashed / PC Graphics Unleashed.iso / ch09 / draw.c next >
C/C++ Source or Header  |  1994-09-15  |  5KB  |  235 lines

  1. // DRAW.C
  2. #include <conio.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <graphics.h>
  6. #include <math.h>
  7.  
  8. #define TOL 0.0005
  9. #define PI  3.14159265358979323846
  10.  
  11. typedef struct {
  12.  float x,y,z;
  13. } POINT3D;
  14.  
  15. typedef struct {
  16.  int x,y;
  17. } POINTint;
  18.  
  19.  
  20. /* World Limits in 2D */
  21. float WXleft;
  22. float WXright;
  23. float WYtop;
  24. float WYbottom;
  25.  
  26. /* Device Limits */
  27. int DXmin;
  28. int DYmin;
  29. int DYmax;
  30. int DXmax;
  31.  
  32. /* Rotations for 3D View in Radians*/
  33. float RX;
  34. float RY;
  35. float RZ;
  36. float COSRX;
  37. float SINRX;
  38. float COSRY;
  39. float SINRY;
  40. float COSRZ;
  41. float SINRZ;
  42.  
  43.  
  44.  
  45. void InitGraphics(void);
  46. float DegToRad(float deg);
  47. float RadToDeg(float rad);
  48. POINT3D World3DToWorld2D(POINT3D p);
  49. POINTint World2DToDevice(POINT3D p);
  50. void drawpoint(POINT3D p1);
  51. void drawline(POINT3D p1,POINT3D p2);
  52. void drawaxis(void);
  53. void SetAxesAngles(float rx, float ry, float rz);
  54.  
  55.  
  56. void main()
  57. {
  58.   POINT3D p;
  59.   InitGraphics();
  60.  
  61.   /* World Limits */
  62.   WXleft   = -1.2;
  63.   WXright  =  1.2;
  64.   WYtop    =  1.2;
  65.   WYbottom = -1.2;
  66.  
  67.   /* Device Limits On A Viewport */
  68.   DXmin = 0.0;
  69.   DYmin = 0.0;
  70.   DYmax = getmaxy()/2;
  71.   DXmax = getmaxy()/2;
  72.  
  73.   /* Draw A 2X2 Grid */
  74.   setcolor(WHITE);
  75.   rectangle(0,0,getmaxy(),getmaxy());
  76.   line(getmaxy()/2,0,getmaxy()/2,getmaxy());
  77.   line(0,getmaxy()/2,getmaxy(),getmaxy()/2);
  78.  
  79.   /* Initialize a 3D point */
  80.   p.x = 0.5;
  81.   p.y = 0.2;
  82.   p.z = 0.5;
  83.  
  84.   /* TOP VIEW */
  85.   setviewport(0,0,getmaxy()/2,getmaxy()/2,1);
  86.   SetAxesAngles(90, 0, 0);
  87.   drawaxis();
  88.   drawpoint(p);
  89.  
  90.   /* ISO VIEW */
  91.   setviewport(getmaxy()/2,0,getmaxy(),getmaxy()/2,1);
  92.   SetAxesAngles(20, -15, -5);
  93.   drawaxis();
  94.   drawpoint(p);
  95.  
  96.   /* FRONT VIEW */
  97.   setviewport(0,getmaxy()/2,getmaxy()/2,getmaxy(),1);
  98.   SetAxesAngles(0, 0, 0);
  99.   drawaxis();
  100.   drawpoint(p);
  101.  
  102.   /* SIDE VIEW */
  103.   setviewport(getmaxy()/2,getmaxy()/2,getmaxy(),getmaxy(),1);
  104.   SetAxesAngles(0, -90, 0);
  105.   drawaxis();
  106.   drawpoint(p);
  107.  
  108.   getch();
  109.   closegraph();
  110. }
  111.  
  112. /* /////////////////////////////////////////////////////// */
  113.  
  114. void InitGraphics(void)
  115. {
  116.  int gdriver = DETECT, gmode, errorcode;
  117.  initgraph(&gdriver, &gmode, "");
  118.  if (gdriver != VGA) {
  119.   printf("VGA graphics card required.\n");
  120.   exit(1);
  121.  }
  122.  errorcode = graphresult();
  123.  if (errorcode != grOk)  /* an error occurred */
  124.  {
  125.    printf("Graphics error: %s\n", grapherrormsg(errorcode));
  126.    printf("Press any key to halt:");
  127.    getch();
  128.    exit(1); /* terminate with an error code */
  129.  }
  130.  setviewport(0,0,getmaxx(),getmaxy(),1);
  131. }
  132.  
  133. float DegToRad(float deg)
  134. {
  135.  return(deg*PI/180.0);
  136. }
  137.  
  138. float RadToDeg(float rad)
  139. {
  140.  return(rad*180.0/PI);
  141. }
  142.  
  143. void SetAxesAngles(float rx, float ry, float rz) {
  144.     RX = DegToRad(rx);
  145.     RY = DegToRad(ry);
  146.     RZ = DegToRad(rz);
  147.     COSRX = cos(RX);
  148.     SINRX = sin(RX);
  149.     COSRY = cos(RY);
  150.     SINRY = sin(RY);
  151.     COSRZ = cos(RZ);
  152.     SINRZ = sin(RZ);
  153. }
  154.  
  155.  
  156.  
  157. POINT3D World3DToWorld2D(POINT3D p)
  158. {
  159.   POINT3D ptemp;
  160.   ptemp = p;
  161.   if (RX) {
  162.     ptemp.x  = p.x;
  163.     ptemp.y  = COSRX*p.y - SINRX*p.z;
  164.     ptemp.z  = SINRX*p.y + COSRX*p.z;
  165.     p = ptemp;
  166.   }
  167.   if (RY) {
  168.     ptemp.x  = COSRY*p.x + SINRY*p.z;
  169.     ptemp.y  = p.y;
  170.     ptemp.z  = -SINRY*p.x + COSRY*p.z;
  171.     p = ptemp;
  172.   }
  173.   if (RZ) {
  174.     ptemp.x  = COSRZ*p.x - SINRZ*p.y;
  175.     ptemp.y  = SINRZ*p.x + COSRZ*p.y;
  176.     ptemp.z  = p.z;
  177.   }
  178.   if (fabs(ptemp.x) < TOL)  ptemp.x = 0.0;
  179.   if (fabs(ptemp.y) < TOL)  ptemp.y = 0.0;
  180.   if (fabs(ptemp.z) < TOL)  ptemp.z = 0.0;
  181.   return(ptemp);
  182. }
  183.  
  184. POINTint World2DToDevice(POINT3D p)
  185. {
  186.  
  187.  POINTint ptemp;
  188.  ptemp.x = (WXleft-p.x)*(DXmax-DXmin)/(WXleft-WXright) + DXmin + 0.5;
  189.  ptemp.y = (WYtop-p.y)*(DYmax-DYmin)/(WYtop-WYbottom) + DYmin + 0.5;
  190.  return(ptemp);
  191.  
  192. }
  193.  
  194. void drawpoint(POINT3D p1)
  195. {
  196.  /* draws a 3D point   */
  197.  POINTint p2;
  198.  p1.z = -p1.z;
  199.  p2 = World2DToDevice(World3DToWorld2D(p1));
  200.  //circle(p2.x,p2.y,2);
  201.  rectangle(p2.x - 2, p2.y - 2, p2.x + 2, p2.y + 2);
  202. }
  203.  
  204. void drawline(POINT3D p1,POINT3D p2)
  205. {
  206.  /* draws a 3D line  */
  207.   POINTint p11,p22;
  208.   p1.z = -p1.z;
  209.   p2.z = -p2.z;
  210.   p11  = World2DToDevice(World3DToWorld2D(p1));
  211.   p22  = World2DToDevice(World3DToWorld2D(p2));
  212.   line(p11.x,p11.y,p22.x,p22.y);
  213. }
  214.  
  215. void drawaxis(void) {
  216.   POINT3D p1,p2;
  217.  
  218.   p1.x = p1.y = p1.z = 0;
  219.  
  220.   p2.x = 1; p2.y = 0; p2.z=0;
  221.   setcolor(RED);
  222.   drawline(p1,p2);
  223.  
  224.   p2.x = 0; p2.y = 1; p2.z=0;
  225.   setcolor(GREEN);
  226.   drawline(p1,p2);
  227.  
  228.   p2.x = 0; p2.y = 0; p2.z=1;
  229.   setcolor(BLUE);
  230.   drawline(p1,p2);
  231.  
  232.   setcolor(WHITE);
  233. }
  234.  
  235.